React์ experimental_useContextSelector๋ฅผ ์ฌ์ธต ๋ถ์ํ์ฌ, ๋ณต์กํ ์ ํ๋ฆฌ์ผ์ด์ ์์ ์ปจํ ์คํธ ์ต์ ํ์ ํจ์จ์ ์ธ ์ปดํฌ๋ํธ ๋ฆฌ๋ ๋๋ง์ ์ํ ์ด์ ์ ํ๊ตฌํฉ๋๋ค.
React experimental_useContextSelector: ์ปจํ ์คํธ ์ต์ ํ ๋ง์คํฐํ๊ธฐ
React์ Context API๋ prop ๋๋ฆด๋ง ์์ด ์ปดํฌ๋ํธ ํธ๋ฆฌ ์ ์ฒด์ ๋ฐ์ดํฐ๋ฅผ ๊ณต์ ํ ์ ์๋ ๊ฐ๋ ฅํ ๋ฉ์ปค๋์ฆ์ ์ ๊ณตํฉ๋๋ค. ๊ทธ๋ฌ๋ ์ปจํ
์คํธ ๊ฐ์ด ์์ฃผ ๋ณ๊ฒฝ๋๋ ๋ณต์กํ ์ ํ๋ฆฌ์ผ์ด์
์์๋ React Context์ ๊ธฐ๋ณธ ๋์์ด ๋ถํ์ํ ๋ฆฌ๋ ๋๋ง์ ์ ๋ฐํ์ฌ ์ฑ๋ฅ์ ์ํฅ์ ๋ฏธ์น ์ ์์ต๋๋ค. ๋ฐ๋ก ์ด ์ง์ ์์ experimental_useContextSelector๊ฐ ๋ฑ์ฅํฉ๋๋ค. ์ด ๋ธ๋ก๊ทธ ํฌ์คํธ์์๋ React ์ปจํ
์คํธ ์ฌ์ฉ์ ์ต์ ํํ๊ธฐ ์ํด experimental_useContextSelector๋ฅผ ์ดํดํ๊ณ ๊ตฌํํ๋ ๋ฐฉ๋ฒ์ ์๋ดํฉ๋๋ค.
React ์ปจํ ์คํธ ๋ฌธ์ ์ดํดํ๊ธฐ
experimental_useContextSelector๋ฅผ ์ดํด๋ณด๊ธฐ ์ ์, ์ด๊ฒ์ด ํด๊ฒฐํ๊ณ ์ ํ๋ ๊ทผ๋ณธ์ ์ธ ๋ฌธ์ ๋ฅผ ์ดํดํ๋ ๊ฒ์ด ์ค์ํฉ๋๋ค. ์ปจํ
์คํธ ๊ฐ์ด ๋ณ๊ฒฝ๋๋ฉด, ํด๋น ์ปจํ
์คํธ๋ฅผ ์ฌ์ฉํ๋ ๋ชจ๋ ์ปดํฌ๋ํธ๋ ์ปจํ
์คํธ ๊ฐ์ ์ผ๋ถ๋ง ์ฌ์ฉํ๋๋ผ๋ ๋ฆฌ๋ ๋๋ง๋ฉ๋๋ค. ์ด๋ฌํ ๋ฌด๋ถ๋ณํ ๋ฆฌ๋ ๋๋ง์ ํนํ ๋ณต์กํ UI๋ฅผ ๊ฐ์ง ๋๊ท๋ชจ ์ ํ๋ฆฌ์ผ์ด์
์์ ์ฌ๊ฐํ ์ฑ๋ฅ ๋ณ๋ชฉ ํ์์ ์ผ์ผํฌ ์ ์์ต๋๋ค.
์ ์ญ ํ ๋ง ์ปจํ ์คํธ๋ฅผ ์๋ก ๋ค์ด๋ณด๊ฒ ์ต๋๋ค:
const ThemeContext = React.createContext({
theme: 'light',
toggleTheme: () => {},
accentColor: 'blue'
});
function ThemedComponent() {
const { theme, accentColor } = React.useContext(ThemeContext);
return (
<div style={{ backgroundColor: theme === 'light' ? '#fff' : '#000', color: theme === 'light' ? '#000' : '#fff' }}>
<p>Current Theme: {theme}</p>
<p>Accent Color: {accentColor}</p>
</div>
);
}
function ThemeToggleButton() {
const { toggleTheme } = React.useContext(ThemeContext);
return (<button onClick={toggleTheme}>Toggle Theme</button>);
}
๋ง์ฝ accentColor๊ฐ ๋ณ๊ฒฝ๋๋ฉด, ThemeToggleButton์ toggleTheme ํจ์๋ง ์ฌ์ฉํจ์๋ ๋ถ๊ตฌํ๊ณ ๋ฆฌ๋ ๋๋ง๋ฉ๋๋ค. ์ด ๋ถํ์ํ ๋ฆฌ๋ ๋๋ง์ ์์ ๋ญ๋น์ด๋ฉฐ ์ฑ๋ฅ์ ์ ํ์ํฌ ์ ์์ต๋๋ค.
experimental_useContextSelector ์๊ฐ
React์ ๋ถ์์ (์คํ์ ) API์ ์ผ๋ถ์ธ experimental_useContextSelector๋ ์ปจํ
์คํธ ๊ฐ์ ํน์ ๋ถ๋ถ๋ง ๊ตฌ๋
ํ ์ ์๊ฒ ํด์ค๋๋ค. ์ด ์ ํ์ ๊ตฌ๋
์ ์ปดํฌ๋ํธ๊ฐ ์ฌ์ฉํ๋ ์ปจํ
์คํธ์ ์ผ๋ถ๊ฐ ์ค์ ๋ก ๋ณ๊ฒฝ๋์์ ๋๋ง ์ปดํฌ๋ํธ๊ฐ ๋ฆฌ๋ ๋๋ง๋๋๋ก ๋ณด์ฅํฉ๋๋ค. ์ด๋ ๋ถํ์ํ ๋ฆฌ๋ ๋๋ง ํ์๋ฅผ ์ค์ฌ ์๋นํ ์ฑ๋ฅ ํฅ์์ ๊ฐ์ ธ์ต๋๋ค.
์ค์ ์ฐธ๊ณ : experimental_useContextSelector๋ ์คํ์ API์ด๋ฏ๋ก, ํฅํ React ๋ฒ์ ์์ ๋ณ๊ฒฝ๋๊ฑฐ๋ ์ ๊ฑฐ๋ ์ ์์ต๋๋ค. ์ฃผ์ํด์ ์ฌ์ฉํ๊ณ ํ์ํ ๊ฒฝ์ฐ ์ฝ๋๋ฅผ ์
๋ฐ์ดํธํ ์ค๋น๋ฅผ ํด์ผ ํฉ๋๋ค.
experimental_useContextSelector์ ์๋ ๋ฐฉ์
experimental_useContextSelector๋ ๋ ๊ฐ์ง ์ธ์๋ฅผ ๋ฐ์ต๋๋ค:
- ์ปจํ
์คํธ ๊ฐ์ฒด:
React.createContext๋ฅผ ์ฌ์ฉํ์ฌ ์์ฑํ ์ปจํ ์คํธ ๊ฐ์ฒด์ ๋๋ค. - ์ ๋ ํฐ ํจ์: ์ ์ฒด ์ปจํ ์คํธ ๊ฐ์ ์ ๋ ฅ์ผ๋ก ๋ฐ์ ์ปดํฌ๋ํธ๊ฐ ํ์๋ก ํ๋ ํน์ ์ปจํ ์คํธ ๋ถ๋ถ์ ๋ฐํํ๋ ํจ์์ ๋๋ค.
์ ๋ ํฐ ํจ์๋ ํํฐ ์ญํ ์ ํ์ฌ ์ปจํ ์คํธ์์ ๊ด๋ จ ๋ฐ์ดํฐ๋ง ์ถ์ถํ ์ ์๊ฒ ํด์ค๋๋ค. ๊ทธ๋ฌ๋ฉด React๋ ์ด ์ ๋ ํฐ๋ฅผ ์ฌ์ฉํ์ฌ ์ปจํ ์คํธ ๊ฐ์ด ๋ณ๊ฒฝ๋ ๋ ์ปดํฌ๋ํธ๊ฐ ๋ฆฌ๋ ๋๋ง๋์ด์ผ ํ๋์ง๋ฅผ ๊ฒฐ์ ํฉ๋๋ค.
experimental_useContextSelector ๊ตฌํํ๊ธฐ
์ด์ ์์ ๋ฅผ experimental_useContextSelector๋ฅผ ์ฌ์ฉํ๋๋ก ๋ฆฌํฉํฐ๋งํด ๋ณด๊ฒ ์ต๋๋ค:
import { unstable_useContextSelector as useContextSelector } from 'react';
const ThemeContext = React.createContext({
theme: 'light',
toggleTheme: () => {},
accentColor: 'blue'
});
function ThemedComponent() {
const { theme, accentColor } = useContextSelector(ThemeContext, (value) => ({
theme: value.theme,
accentColor: value.accentColor
}));
return (
<div style={{ backgroundColor: theme === 'light' ? '#fff' : '#000', color: theme === 'light' ? '#000' : '#fff' }}>
<p>Current Theme: {theme}</p>
<p>Accent Color: {accentColor}</p>
</div>
);
}
function ThemeToggleButton() {
const toggleTheme = useContextSelector(ThemeContext, (value) => value.toggleTheme);
return (<button onClick={toggleTheme}>Toggle Theme</button>);
}
์ด ๋ฆฌํฉํฐ๋ง๋ ์ฝ๋์์๋:
unstable_useContextSelector๋ฅผ importํ๊ณ ๊ฐ๊ฒฐ์ฑ์ ์ํดuseContextSelector๋ก ์ด๋ฆ์ ๋ฐ๊ฟ๋๋ค.ThemedComponent์์ ์ ๋ ํฐ ํจ์๋ ์ปจํ ์คํธ์์theme๊ณผaccentColor๋ง ์ถ์ถํฉ๋๋ค.ThemeToggleButton์์ ์ ๋ ํฐ ํจ์๋ ์ปจํ ์คํธ์์toggleTheme๋ง ์ถ์ถํฉ๋๋ค.
์ด์ accentColor๊ฐ ๋ณ๊ฒฝ๋์ด๋, ThemeToggleButton์ ๋ ์ด์ ๋ฆฌ๋ ๋๋ง๋์ง ์์ต๋๋ค. ์๋ํ๋ฉด ์ด ์ปดํฌ๋ํธ์ ์
๋ ํฐ ํจ์๋ toggleTheme์๋ง ์์กดํ๊ธฐ ๋๋ฌธ์
๋๋ค. ์ด๊ฒ์ด ๋ฐ๋ก experimental_useContextSelector๊ฐ ์ด๋ป๊ฒ ๋ถํ์ํ ๋ฆฌ๋ ๋๋ง์ ๋ฐฉ์งํ ์ ์๋์ง๋ฅผ ๋ณด์ฌ์ค๋๋ค.
experimental_useContextSelector ์ฌ์ฉ์ ์ด์
- ์ฑ๋ฅ ํฅ์: ๋ถํ์ํ ๋ฆฌ๋ ๋๋ง์ ์ค์ฌ ํนํ ๋ณต์กํ ์ ํ๋ฆฌ์ผ์ด์ ์์ ๋ ๋์ ์ฑ๋ฅ์ ์ ๊ณตํฉ๋๋ค.
- ์ธ๋ถํ๋ ์ ์ด: ์ปจํ ์คํธ๊ฐ ๋ณ๊ฒฝ๋ ๋ ์ด๋ค ์ปดํฌ๋ํธ๊ฐ ๋ฆฌ๋ ๋๋ง๋ ์ง ์ ๋ฐํ๊ฒ ์ ์ดํ ์ ์์ต๋๋ค.
- ๋จ์ํ๋ ์ต์ ํ: ๋ณต์กํ ๋ฉ๋ชจ์ด์ ์ด์ ๊ธฐ์ ์ ์์กดํ์ง ์๊ณ ์ปจํ ์คํธ ์ฌ์ฉ์ ์ต์ ํํ ์ ์๋ ๊ฐ๋จํ ๋ฐฉ๋ฒ์ ์ ๊ณตํฉ๋๋ค.
๊ณ ๋ ค์ฌํญ ๋ฐ ์ ์ฌ์ ๋จ์
- ์คํ์ API: ์คํ์ API๋ก์
experimental_useContextSelector๋ ๋ณ๊ฒฝ๋๊ฑฐ๋ ์ ๊ฑฐ๋ ์ ์์ต๋๋ค. React ๋ฆด๋ฆฌ์ค ๋ ธํธ๋ฅผ ์ฃผ์ํ๊ณ ์ฝ๋๋ฅผ ์์ ํ ์ค๋น๋ฅผ ํด์ผ ํฉ๋๋ค. - ๋ณต์ก์ฑ ์ฆ๊ฐ: ์ผ๋ฐ์ ์ผ๋ก ์ต์ ํ๋ฅผ ๋จ์ํํ์ง๋ง, ์ฝ๋์ ์ฝ๊ฐ์ ๋ณต์ก์ฑ์ ์ถ๊ฐํ ์ ์์ต๋๋ค. ๋์ ํ๊ธฐ ์ ์ ์ถ๊ฐ๋ ๋ณต์ก์ฑ๋ณด๋ค ์ด์ ์ด ๋ ํฐ์ง ํ์ธํ์ญ์์ค.
- ์ ๋ ํฐ ํจ์ ์ฑ๋ฅ: ์ ๋ ํฐ ํจ์๋ ์ฑ๋ฅ์ด ์ข์์ผ ํฉ๋๋ค. ์ ๋ ํฐ ๋ด์์ ๋ณต์กํ ๊ณ์ฐ์ด๋ ๋น์ฉ์ด ๋ง์ด ๋๋ ์์ ์ ํผํ์ญ์์ค. ์ด๋ ์ฑ๋ฅ์์ ์ด์ ์ ์์ํ ์ ์์ต๋๋ค.
- ์คํ
์ผ ํด๋ก์ (Stale Closure) ๊ฐ๋ฅ์ฑ: ์
๋ ํฐ ํจ์ ๋ด์์ ๋ฐ์ํ ์ ์๋ ์คํ
์ผ ํด๋ก์ ์ ์ ์ํด์ผ ํฉ๋๋ค. ์
๋ ํฐ ํจ์๊ฐ ์ต์ ์ปจํ
์คํธ ๊ฐ์ ์ ๊ทผํ ์ ์๋๋ก ํ์ญ์์ค. ํ์ํ ๊ฒฝ์ฐ
useCallback์ ์ฌ์ฉํ์ฌ ์ ๋ ํฐ ํจ์๋ฅผ ๋ฉ๋ชจ์ด์ ์ด์ ํ๋ ๊ฒ์ ๊ณ ๋ คํ์ญ์์ค.
์ค์ ์์ ๋ฐ ์ฌ์ฉ ์ฌ๋ก
experimental_useContextSelector๋ ๋ค์๊ณผ ๊ฐ์ ์๋๋ฆฌ์ค์์ ํนํ ์ ์ฉํฉ๋๋ค:
- ๋๊ท๋ชจ ํผ: ์ปจํ
์คํธ๋ก ํผ ์ํ๋ฅผ ๊ด๋ฆฌํ ๋,
experimental_useContextSelector๋ฅผ ์ฌ์ฉํ์ฌ ์ํ ๋ณ๊ฒฝ์ ์ง์ ์ ์ธ ์ํฅ์ ๋ฐ๋ ์ ๋ ฅ ํ๋๋ง ๋ฆฌ๋ ๋๋งํฉ๋๋ค. ์๋ฅผ ๋ค์ด, ์ ์์๊ฑฐ๋ ํ๋ซํผ์ ๊ฒฐ์ ํผ์ ์ฃผ์, ๊ฒฐ์ ๋ฐ ๋ฐฐ์ก ์ต์ ๋ณ๊ฒฝ ์ ๋ฆฌ๋ ๋๋ง์ ์ต์ ํํ์ฌ ํฐ ์ด์ ์ ์ป์ ์ ์์ต๋๋ค. - ๋ณต์กํ ๋ฐ์ดํฐ ๊ทธ๋ฆฌ๋: ์๋ง์ ์ด๊ณผ ํ์ด ์๋ ๋ฐ์ดํฐ ๊ทธ๋ฆฌ๋์์,
experimental_useContextSelector๋ฅผ ์ฌ์ฉํ์ฌ ํน์ ์ ์ด๋ ํ๋ง ์ ๋ฐ์ดํธ๋ ๋ ๋ฆฌ๋ ๋๋ง์ ์ต์ ํํฉ๋๋ค. ์ค์๊ฐ ์ฃผ๊ฐ๋ฅผ ํ์ํ๋ ๊ธ์ต ๋์๋ณด๋๋ ์ด๋ฅผ ํ์ฉํ์ฌ ์ ์ฒด ๋์๋ณด๋๋ฅผ ๋ฆฌ๋ ๋๋งํ์ง ์๊ณ ๊ฐ๋ณ ์ฃผ์ ์์ธ๋ฅผ ํจ์จ์ ์ผ๋ก ์ ๋ฐ์ดํธํ ์ ์์ต๋๋ค. - ํ
๋ง ์์คํ
: ์ด์ ์์ ์์ ๋ณด์ฌ์ฃผ์๋ฏ์ด,
experimental_useContextSelector๋ฅผ ์ฌ์ฉํ์ฌ ํ ๋ง๊ฐ ๋ณ๊ฒฝ๋ ๋ ํน์ ํ ๋ง ์์ฑ์ ์์กดํ๋ ์ปดํฌ๋ํธ๋ง ๋ฆฌ๋ ๋๋ง๋๋๋ก ํฉ๋๋ค. ๋๊ท๋ชจ ์กฐ์ง์ ์ํ ๊ธ๋ก๋ฒ ์คํ์ผ ๊ฐ์ด๋๋ ๋์ ์ผ๋ก ๋ณ๊ฒฝ๋๋ ๋ณต์กํ ํ ๋ง๋ฅผ ๊ตฌํํ ์ ์์ผ๋ฏ๋ก ์ด ์ต์ ํ๊ฐ ๋งค์ฐ ์ค์ํฉ๋๋ค. - ์ธ์ฆ ์ปจํ
์คํธ: ์ปจํ
์คํธ๋ก ์ธ์ฆ ์ํ(์: ์ฌ์ฉ์ ๋ก๊ทธ์ธ ์ํ, ์ฌ์ฉ์ ์ญํ )๋ฅผ ๊ด๋ฆฌํ ๋,
experimental_useContextSelector๋ฅผ ์ฌ์ฉํ์ฌ ์ธ์ฆ ์ํ ๋ณ๊ฒฝ์ ์์กดํ๋ ์ปดํฌ๋ํธ๋ง ๋ฆฌ๋ ๋๋งํฉ๋๋ค. ๋ค์ํ ๊ณ์ ์ ํ์ ๋ฐ๋ผ ๊ธฐ๋ฅ์ด ์ ๊ธ ํด์ ๋๋ ๊ตฌ๋ ๊ธฐ๋ฐ ์น์ฌ์ดํธ๋ฅผ ์๊ฐํด๋ณด์ญ์์ค. ์ฌ์ฉ์์ ๊ตฌ๋ ์ ํ ๋ณ๊ฒฝ์ ํด๋น๋๋ ์ปดํฌ๋ํธ์๋ง ๋ฆฌ๋ ๋๋ง์ ํธ๋ฆฌ๊ฑฐํ ๊ฒ์ ๋๋ค. - ๊ตญ์ ํ(i18n) ์ปจํ
์คํธ: ์ปจํ
์คํธ๋ก ํ์ฌ ์ ํ๋ ์ธ์ด ๋๋ ๋ก์ผ์ผ ์ค์ ์ ๊ด๋ฆฌํ ๋,
experimental_useContextSelector๋ฅผ ์ฌ์ฉํ์ฌ ํ ์คํธ ์ฝํ ์ธ ๋ฅผ ์ ๋ฐ์ดํธํด์ผ ํ๋ ์ปดํฌ๋ํธ๋ง ๋ฆฌ๋ ๋๋งํฉ๋๋ค. ์ฌ๋ฌ ์ธ์ด๋ฅผ ์ง์ํ๋ ์ฌํ ์์ฝ ์น์ฌ์ดํธ๋ ์ด๋ฅผ ์ฌ์ฉํ์ฌ ๋ค๋ฅธ ์ฌ์ดํธ ์์์ ๋ถํ์ํ ์ํฅ์ ์ฃผ์ง ์๊ณ UI ์์์ ํ ์คํธ๋ฅผ ์๋ก ๊ณ ์น ์ ์์ต๋๋ค.
experimental_useContextSelector ์ฌ์ฉ์ ์ํ ๋ชจ๋ฒ ์ฌ๋ก
- ํ๋กํ์ผ๋ง์ผ๋ก ์์ํ๊ธฐ:
experimental_useContextSelector๋ฅผ ๊ตฌํํ๊ธฐ ์ ์, React ํ๋กํ์ผ๋ฌ๋ฅผ ์ฌ์ฉํ์ฌ ์ปจํ ์คํธ ๋ณ๊ฒฝ์ผ๋ก ์ธํด ๋ถํ์ํ๊ฒ ๋ฆฌ๋ ๋๋ง๋๋ ์ปดํฌ๋ํธ๋ฅผ ์๋ณํ์ญ์์ค. ์ด๋ ์ต์ ํ ๋ ธ๋ ฅ์ ํจ๊ณผ์ ์ผ๋ก ์ง์คํ๋ ๋ฐ ๋์์ด ๋ฉ๋๋ค. - ์ ๋ ํฐ๋ ๊ฐ๋จํ๊ฒ ์ ์งํ๊ธฐ: ์ ๋ ํฐ ํจ์๋ ๊ฐ๋ฅํ ํ ๊ฐ๋จํ๊ณ ํจ์จ์ ์ด์ด์ผ ํฉ๋๋ค. ์ ๋ ํฐ ๋ด์์ ๋ณต์กํ ๋ก์ง์ด๋ ๋น์ฉ์ด ๋ง์ด ๋๋ ๊ณ์ฐ์ ํผํ์ญ์์ค.
- ํ์ํ ๋ ๋ฉ๋ชจ์ด์ ์ด์
์ฌ์ฉํ๊ธฐ: ์
๋ ํฐ ํจ์๊ฐ props๋ ์์ฃผ ๋ณ๊ฒฝ๋ ์ ์๋ ๋ค๋ฅธ ๋ณ์์ ์์กดํ๋ ๊ฒฝ์ฐ,
useCallback์ ์ฌ์ฉํ์ฌ ์ ๋ ํฐ ํจ์๋ฅผ ๋ฉ๋ชจ์ด์ ์ด์ ํ์ญ์์ค. - ๊ตฌํ์ ์ฒ ์ ํ ํ
์คํธํ๊ธฐ: ์์์น ๋ชปํ ๋์์ด๋ ํ๊ท๋ฅผ ๋ฐฉ์งํ๊ธฐ ์ํด
experimental_useContextSelector๊ตฌํ์ ์ฒ ์ ํ ํ ์คํธํ์ญ์์ค. - ๋์ ๊ณ ๋ คํ๊ธฐ:
experimental_useContextSelector์ ์์กดํ๊ธฐ ์ ์React.memo๋useMemo์ ๊ฐ์ ๋ค๋ฅธ ์ต์ ํ ๊ธฐ๋ฒ์ ํ๊ฐํ์ญ์์ค. ๋๋ก๋ ๋ ๊ฐ๋จํ ํด๊ฒฐ์ฑ ์ผ๋ก ์ํ๋ ์ฑ๋ฅ ํฅ์์ ๋ฌ์ฑํ ์ ์์ต๋๋ค. - ์ฌ์ฉ๋ฒ ๋ฌธ์ํํ๊ธฐ:
experimental_useContextSelector๋ฅผ ์ด๋์ ์ ์ฌ์ฉํ๋์ง ๋ช ํํ๊ฒ ๋ฌธ์ํํ์ญ์์ค. ์ด๋ ๋ค๋ฅธ ๊ฐ๋ฐ์๋ค์ด ์ฝ๋๋ฅผ ์ดํดํ๊ณ ๋ฏธ๋์ ์ ์ง๋ณด์ํ๋ ๋ฐ ๋์์ด ๋ ๊ฒ์ ๋๋ค.
๋ค๋ฅธ ์ต์ ํ ๊ธฐ๋ฒ๊ณผ์ ๋น๊ต
experimental_useContextSelector๋ ์ปจํ
์คํธ ์ต์ ํ๋ฅผ ์ํ ๊ฐ๋ ฅํ ๋๊ตฌ์ด์ง๋ง, React์ ๋ค๋ฅธ ์ต์ ํ ๊ธฐ๋ฒ๊ณผ ์ด๋ป๊ฒ ๋น๊ต๋๋์ง ์ดํดํ๋ ๊ฒ์ด ์ค์ํฉ๋๋ค:
- React.memo:
React.memo๋ ํจ์ํ ์ปดํฌ๋ํธ๋ฅผ ๋ฉ๋ชจ์ด์ ์ด์ ํ๋ ๊ณ ์ฐจ ์ปดํฌ๋ํธ(HOC)์ ๋๋ค. props๊ฐ ๋ณ๊ฒฝ๋์ง ์์๋ค๋ฉด(์์ ๋น๊ต) ๋ฆฌ๋ ๋๋ง์ ๋ฐฉ์งํฉ๋๋ค.experimental_useContextSelector์ ๋ฌ๋ฆฌ,React.memo๋ ์ปจํ ์คํธ ๋ณ๊ฒฝ์ด ์๋ prop ๋ณ๊ฒฝ์ ๊ธฐ๋ฐ์ผ๋ก ์ต์ ํํฉ๋๋ค. props๋ฅผ ์์ฃผ ๋ฐ๊ณ ๋ ๋๋ง ๋น์ฉ์ด ๋น์ผ ์ปดํฌ๋ํธ์ ๊ฐ์ฅ ํจ๊ณผ์ ์ ๋๋ค. - useMemo:
useMemo๋ ํจ์ ํธ์ถ ๊ฒฐ๊ณผ๋ฅผ ๋ฉ๋ชจ์ด์ ์ด์ ํ๋ ํ ์ ๋๋ค. ์์กด์ฑ์ด ๋ณ๊ฒฝ๋์ง ์๋ ํ ํจ์๊ฐ ๋ค์ ์คํ๋๋ ๊ฒ์ ๋ฐฉ์งํฉ๋๋ค.useMemo๋ฅผ ์ฌ์ฉํ์ฌ ์ปดํฌ๋ํธ ๋ด์ ํ์ ๋ฐ์ดํฐ๋ฅผ ๋ฉ๋ชจ์ด์ ์ด์ ํ์ฌ ๋ถํ์ํ ์ฌ๊ณ์ฐ์ ๋ฐฉ์งํ ์ ์์ต๋๋ค. - useCallback:
useCallback์ ํจ์๋ฅผ ๋ฉ๋ชจ์ด์ ์ด์ ํ๋ ํ ์ ๋๋ค. ์์กด์ฑ์ด ๋ณ๊ฒฝ๋์ง ์๋ ํ ํจ์๊ฐ ๋ค์ ์์ฑ๋๋ ๊ฒ์ ๋ฐฉ์งํฉ๋๋ค. ์ด๋ ์์ ์ปดํฌ๋ํธ์ ํจ์๋ฅผ props๋ก ์ ๋ฌํ ๋ ์ ์ฉํ๋ฉฐ, ๋ถํ์ํ ๋ฆฌ๋ ๋๋ง์ ๋ฐฉ์งํฉ๋๋ค. - Redux ์
๋ ํฐ ํจ์ (Reselect ์ฌ์ฉ): Redux์ ๊ฐ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ Redux ์คํ ์ด์์ ๋ฐ์ดํฐ๋ฅผ ํจ์จ์ ์ผ๋ก ํ์์ํค๊ธฐ ์ํด ์
๋ ํฐ ํจ์(์ฃผ๋ก Reselect์ ํจ๊ป)๋ฅผ ์ฌ์ฉํฉ๋๋ค. ์ด ์
๋ ํฐ๋ค์
experimental_useContextSelector์ ํจ๊ป ์ฌ์ฉ๋๋ ์ ๋ ํฐ ํจ์์ ๊ฐ๋ ์ ์ผ๋ก ์ ์ฌํ์ง๋ง, Redux์ ํนํ๋์ด ์์ผ๋ฉฐ Redux ์คํ ์ด์ ์ํ์ ๋ํด ์๋ํฉ๋๋ค.
์ต์์ ์ต์ ํ ๊ธฐ๋ฒ์ ํน์ ์ํฉ์ ๋ฐ๋ผ ๋ค๋ฆ ๋๋ค. ์ต์ ์ ์ฑ๋ฅ์ ๋ฌ์ฑํ๊ธฐ ์ํด ์ด๋ฌํ ๊ธฐ๋ฒ๋ค์ ์กฐํฉํ์ฌ ์ฌ์ฉํ๋ ๊ฒ์ ๊ณ ๋ คํ์ญ์์ค.
์ฝ๋ ์์ : ๋ ๋ณต์กํ ์๋๋ฆฌ์ค
๋ ๋ณต์กํ ์๋๋ฆฌ์ค๋ฅผ ๊ณ ๋ คํด ๋ณด๊ฒ ์ต๋๋ค: ์ ์ญ ์์ ์ปจํ ์คํธ๊ฐ ์๋ ์์ ๊ด๋ฆฌ ์ ํ๋ฆฌ์ผ์ด์ ์ ๋๋ค.
import { unstable_useContextSelector as useContextSelector } from 'react';
const TaskContext = React.createContext({
tasks: [],
addTask: () => {},
updateTaskStatus: () => {},
deleteTask: () => {},
filter: 'all',
setFilter: () => {}
});
function TaskList() {
const filteredTasks = useContextSelector(TaskContext, (value) => {
switch (value.filter) {
case 'active':
return value.tasks.filter((task) => !task.completed);
case 'completed':
return value.tasks.filter((task) => task.completed);
default:
return value.tasks;
}
});
return (
<ul>
{filteredTasks.map((task) => (
<li key={task.id}>{task.title}</li>
))}
</ul>
);
}
function TaskFilter() {
const { filter, setFilter } = useContextSelector(TaskContext, (value) => ({
filter: value.filter,
setFilter: value.setFilter
}));
return (
<div>
<button onClick={() => setFilter('all')}>All</button>
<button onClick={() => setFilter('active')}>Active</button>
<button onClick={() => setFilter('completed')}>Completed</button>
</div>
);
}
function TaskAdder() {
const addTask = useContextSelector(TaskContext, (value) => value.addTask);
const [newTaskTitle, setNewTaskTitle] = React.useState('');
const handleSubmit = (e) => {
e.preventDefault();
addTask({ id: Date.now(), title: newTaskTitle, completed: false });
setNewTaskTitle('');
};
return (
<form onSubmit={handleSubmit}>
<input
type="text"
value={newTaskTitle}
onChange={(e) => setNewTaskTitle(e.target.value)}
/>
<button type="submit">Add Task</button>
</form>
);
}
์ด ์์ ์์๋:
TaskList๋filter๋tasks๋ฐฐ์ด์ด ๋ณ๊ฒฝ๋ ๋๋ง ๋ฆฌ๋ ๋๋ง๋ฉ๋๋ค.TaskFilter๋filter๋setFilterํจ์๊ฐ ๋ณ๊ฒฝ๋ ๋๋ง ๋ฆฌ๋ ๋๋ง๋ฉ๋๋ค.TaskAdder๋addTaskํจ์๊ฐ ๋ณ๊ฒฝ๋ ๋๋ง ๋ฆฌ๋ ๋๋ง๋ฉ๋๋ค.
์ด ์ ํ์ ๋ ๋๋ง์ ์์ ์ปจํ ์คํธ๊ฐ ์์ฃผ ๋ณ๊ฒฝ๋ ๋์๋ ์ ๋ฐ์ดํธ๊ฐ ํ์ํ ์ปดํฌ๋ํธ๋ง ๋ฆฌ๋ ๋๋ง๋๋๋ก ๋ณด์ฅํฉ๋๋ค.
๊ฒฐ๋ก
experimental_useContextSelector๋ React Context ์ฌ์ฉ์ ์ต์ ํํ๊ณ ์ ํ๋ฆฌ์ผ์ด์
์ฑ๋ฅ์ ํฅ์์ํค๋ ๋ฐ ์ ์ฉํ ๋๊ตฌ์
๋๋ค. ์ปจํ
์คํธ ๊ฐ์ ํน์ ๋ถ๋ถ์ ์ ํ์ ์ผ๋ก ๊ตฌ๋
ํจ์ผ๋ก์จ ๋ถํ์ํ ๋ฆฌ๋ ๋๋ง์ ์ค์ด๊ณ ์ ํ๋ฆฌ์ผ์ด์
์ ์ ๋ฐ์ ์ธ ๋ฐ์์ฑ์ ํฅ์์ํฌ ์ ์์ต๋๋ค. ํ๋ช
ํ๊ฒ ์ฌ์ฉํ๊ณ , ์ ์ฌ์ ์ธ ๋จ์ ์ ๊ณ ๋ คํ๋ฉฐ, ๊ตฌํ์ ์ฒ ์ ํ ํ
์คํธํ๋ ๊ฒ์ ์์ง ๋ง์ญ์์ค. ์ด ์ต์ ํ๋ฅผ ๊ตฌํํ๊ธฐ ์ ํ์ ํญ์ ํ๋กํ์ผ๋งํ์ฌ ์๋นํ ์ฐจ์ด๋ฅผ ๋ง๋ค์ด๋ด๊ณ ์๋์ง, ๊ทธ๋ฆฌ๊ณ ์๊ธฐ์น ์์ ๋ถ์์ฉ์ ์ผ์ผํค์ง ์๋์ง ํ์ธํ์ญ์์ค.
React๊ฐ ๊ณ์ ๋ฐ์ ํจ์ ๋ฐ๋ผ, ์๋ก์ด ๊ธฐ๋ฅ๊ณผ ์ต์ ํ๋ฅผ ์ํ ๋ชจ๋ฒ ์ฌ๋ก์ ๋ํ ์ ๋ณด๋ฅผ ๊ณ์ ์ ํ๋ ๊ฒ์ด ์ค์ํฉ๋๋ค. experimental_useContextSelector์ ๊ฐ์ ์ปจํ
์คํธ ์ต์ ํ ๊ธฐ์ ์ ๋ง์คํฐํ๋ฉด ๋ ํจ์จ์ ์ด๊ณ ์ฑ๋ฅ์ด ๋ฐ์ด๋ React ์ ํ๋ฆฌ์ผ์ด์
์ ๊ตฌ์ถํ ์ ์์ต๋๋ค.
๋ ์์๋ณด๊ธฐ
- React ๊ณต์ ๋ฌธ์: ์คํ์ API์ ๋ํ ์ ๋ฐ์ดํธ๋ ๊ณต์ React ๋ฌธ์๋ฅผ ์ฃผ์ํ์ญ์์ค.
- ์ปค๋ฎค๋ํฐ ํฌ๋ผ: ํฌ๋ผ์ด๋ ์์
๋ฏธ๋์ด์์ React ์ปค๋ฎค๋ํฐ์ ๊ต๋ฅํ๋ฉฐ ๋ค๋ฅธ ๊ฐ๋ฐ์๋ค์
experimental_useContextSelector์ฌ์ฉ ๊ฒฝํ์ผ๋ก๋ถํฐ ๋ฐฐ์ฐ์ญ์์ค. - ์คํ: ์์ ์ ํ๋ก์ ํธ์์
experimental_useContextSelector๋ฅผ ์คํํ์ฌ ๊ทธ ๊ธฐ๋ฅ๊ณผ ํ๊ณ์ ๋ํ ๋ ๊น์ ์ดํด๋ฅผ ์ป์ผ์ญ์์ค.